home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 050 / madtrb13.arc / WINDOWZ.PAS < prev   
Pascal/Delphi Source File  |  1985-05-19  |  7KB  |  218 lines

  1. { A set of routines for text window manipulation
  2.   By Bela Lubkin
  3.   Borland International Technical Support
  4.   1/10/85
  5.   (For PC-DOS Turbo Pascal version 2 or greater)
  6.  
  7. Notes: These routines cause extreme blinking on the color monitor.  If anyone
  8.        modifies them to decrease this blinking, please upload your modified
  9.        routines to the Borland SIG on CompuServe - GO BOR
  10.  
  11.        REMEMBER to dispose of your windows, or you will quickly run out of
  12.        heap space.  Procedure DRestoreWindow restores a window to the screen
  13.        and then disposes of the window;  procedure DisposeWindow disposes of
  14.        a window.  DO NOT USE Turbo's built in Dispose procedure on a window;
  15.        windows are allocated with GetMem and must be disposed with FreeMem. }
  16.  
  17. Type
  18.   XTCoord=1..80;   { X Text coordinate }
  19.   YTCoord=1..25;   { Y Text coordinate }
  20.   XTCoord0=0..80;  { X Text coordinate + 0 for nothing }
  21.   YTCoord0=0..25;  { Y Text coordinate + 0 for nothing }
  22.   WindowRec=Record
  23.               XSize: XTCoord;
  24.               YSize: YTCoord;
  25.               XPosn: XTCoord;
  26.               YPosn: YTCoord;
  27.               Contents: Array [0..1999] Of Integer;
  28.             End;
  29.   WindowPtr=^WindowRec;
  30.  
  31. Var
  32.   ScreenBase: Integer;  { Segment address of the screen: $B000 for monochrome,
  33.                           $B800 for color }
  34.   WindowXLo: XTCoord;
  35.   WindowYLo: YTCoord;
  36.   WindowXHi: XTCoord;
  37.   WindowYHi: YTCoord;
  38.  
  39. Procedure TurboWindow(XL: XTCoord; YL: YTCoord; XH: XTCoord; YH: YTCoord);
  40. { This procedure provides an entry to Turbo's built in Window procedure }
  41.   Begin
  42.     Window(XL,YL,XH,YH);
  43.   End;
  44.  
  45. Procedure Window(XL: XTCoord; YL: YTCoord; XH: XTCoord; YH: YTCoord);
  46. { This procedure replaces Turbo's built in Window procedure.  It calls the
  47.   original Window procedure, and also keeps track of the window boundaries. }
  48.  
  49.   Begin
  50.     TurboWindow(XL,YL,XH,YH);
  51.     WindowXLo:=XL;
  52.     WindowYLo:=YL;
  53.     WindowXHi:=XH;
  54.     WindowYHi:=YH;
  55.   End;
  56.  
  57. Function SaveWindow(XLow: XTCoord; YLow: YTCoord;
  58.                     XHigh: XTCoord; YHigh:YTCoord): WindowPtr;
  59. { Allocate a WindowRec of the precise size needed to save the window, then
  60.   fill it with the text that is in the window XLow..XHigh, YLow..YHigh.
  61.   Return a pointer to this WindowRec. }
  62.  
  63.   Var
  64.     SW: WindowPtr;
  65.     I: Integer;
  66.     XS: XTCoord;
  67.     YS: YTCoord;
  68.  
  69.   Begin
  70.     XS:=XHigh-XLow+1;
  71.     YS:=YHigh-YLow+1;
  72.     GetMem(SW,2*XS*YS + 4);
  73.     { Allocate 2 bytes for each screen position, + 4 for size and position }
  74.     With SW^ Do
  75.      Begin
  76.       XSize:=XS;
  77.       YSize:=YS;
  78.       XPosn:=XLow;
  79.       YPosn:=YLow;
  80.       For I:=0 To YSize-1 Do
  81.         Move(Mem[ScreenBase:((YPosn+I-1)*80+XPosn-1) Shl 1],
  82.              Contents[I*XSize],XSize Shl 1);
  83.       { For each line of the window,
  84.           Move XSize*2 bytes (1 for char, 1 for attribute) into the Contents
  85.                array.  Leave no holes in the array. }
  86.      End;
  87.     SaveWindow:=SW;
  88.   End;
  89.  
  90. Function SaveCurrentWindow: WindowPtr;
  91.   Begin
  92.     SaveCurrentWindow:=SaveWindow(WindowXLo,WindowYLo,WindowXHi,WindowYHi);
  93.   End;
  94.  
  95. Procedure RestoreWindow(WP: WindowPtr; XPos: XTCoord0; YPos: YTCoord0);
  96. { Given a pointer to a WindowRec, restore the contents of the window.  If
  97.   XPos or YPos is 0, use the XPosn or YPosn that the window was originally
  98.   saved with.  If either is nonzero, use it.  Thus a window can be restored
  99.   exactly with  RestoreWindow(wp,0,0);  or its upper left corner can be
  100.   placed at (2,3) with  RestoreWindow(wp,2,3); }
  101.  
  102.   Var
  103.     I: Integer;
  104.  
  105.   Begin
  106.     With WP^ Do
  107.      Begin
  108.       If XPos=0 Then XPos:=XPosn;
  109.       If YPos=0 Then YPos:=YPosn;
  110.       For I:=0 To YSize-1 Do
  111.         Move(Contents[I*XSize],
  112.              Mem[ScreenBase:2*((YPos+I-1)*80+XPos-1)],XSize*2);
  113.       { For each line of the window,
  114.           Move XSize*2 bytes (1 for char, 1 for attribute) from the Contents
  115.                array onto the screen. }
  116.      End;
  117.   End;
  118.  
  119. Procedure DisposeWindow(Var WP: WindowPtr);
  120. { Dispose of a WindowPtr.  The built in procedure Dispose cannot be used,
  121.   because it will deallocate SizeOf(WindowRec) bytes, even though less may
  122.   have been allocated. }
  123.  
  124.   Begin
  125.     With WP^ Do FreeMem(WP,2*XSize*YSize+4);
  126.     WP:=Nil;
  127.   End;
  128.  
  129. Procedure DRestoreWindow(Var WP: WindowPtr; XPos: XTCoord0; YPos: YTCoord0);
  130. { Restore the contents of a window, then dispose of the saved image }
  131.  
  132.   Begin
  133.     RestoreWindow(WP, XPos, YPos);
  134.     DisposeWindow(WP);
  135.   End;
  136.  
  137. Procedure DRestoreCurrentWindow(Var WP: WindowPtr;
  138.                                 XPos: XTCoord0; YPos: YTCoord0);
  139. { Restore the contents of a window, set the current window to fit the restored
  140.   window, and dispose of the saved image.  A similar procedure
  141.   RestoreCurrentWindow could be written by changing DRestoreWindow to
  142.   RestoreWindow in the last line of the procedure, but I have assumed that
  143.   when you select a window area, you are going to modify it, and not want the
  144.   old image }
  145.  
  146.   Begin
  147.     With WP^ Do
  148.      Begin
  149.       If XPos=0 Then XPos:=XPosn;
  150.       If YPos=0 Then YPos:=YPosn;
  151.       Window(XPos,YPos,XPos+XSize-1,YPos+YSize-1);
  152.      End;
  153.     DRestoreWindow(WP, XPos, YPos);
  154.   End;
  155.  
  156. Procedure DetermineDisplay;
  157. { Set ScreenBase to $B000 or $B800, depending on which display is in use.
  158.   A side effect is that the cursor is left at (1,1) on the screen. }
  159.  
  160.   Var
  161.     M,C: Integer;
  162.     T: Byte;
  163.  
  164.   Begin
  165.     M:=MemW[$B000:0];
  166.     C:=MemW[$B800:0];
  167.     T:=64;
  168.     If (Hi(M)=T) Or (Hi(C)=T) Then T:=65;
  169.     If (Hi(M)=T) Or (Hi(C)=T) Then T:=66;
  170.     GotoXY(1,1);
  171.     Write(Chr(T));
  172.     GotoXY(1,1);
  173.     If Mem[$B000:0]=T Then ScreenBase:=$B000
  174.     Else ScreenBase:=$B800;
  175.     MemW[$B000:0]:=M;
  176.     MemW[$B800:0]:=C;
  177.   End;
  178.  
  179. { Example program -- remove next line to enable }
  180. Var
  181.   X,Y: Byte;
  182.   W,W2: WindowPtr;
  183.   Ch: Char;
  184.  
  185. Begin
  186.   DetermineDisplay; { Set ScreenBase according to the display in use }
  187.   For Y:=1 To 1999 Do
  188.     Write(Chr(Random(95)+32)); { Fill the screen with junk }
  189.   W:=SaveWindow(1,1,80,25); { Save the whole screen }
  190.   Read(Kbd,Ch);
  191.   ClrScr; { Clear it }
  192.   Read(Kbd,Ch);
  193.   DRestoreWindow(W,0,0); { Restore it }
  194.   Read(Kbd,Ch);
  195.   Window(5,4,53,23);
  196.   W:=SaveCurrentWindow; { Save a medium sized window }
  197.   ClrScr; { Wipe that window }
  198.   Read(Kbd,Ch);
  199.   RestoreWindow(W,0,0); { And restore it }
  200.   Window(1,1,80,25);
  201.   Read(Kbd,Ch);
  202.   W2:=SaveWindow(2,2,10,10); { Save a small window }
  203.   ClrScr;
  204.   Read(Kbd,Ch);
  205.   For X:=1 To 72 Do          { Restore it in a square around the edges of }
  206.     RestoreWindow(W2,X,1);   {  the screen }
  207.   For Y:=2 To 17 Do
  208.     RestoreWindow(W2,72,Y);
  209.   For X:=71 DownTo 1 Do
  210.     RestoreWindow(W2,X,17);
  211.   For Y:=16 DownTo 1 Do
  212.     RestoreWindow(W2,1,Y);
  213.   Read(Kbd,Ch);
  214.   DisposeWindow(W2);
  215.   DRestoreWindow(W,0,0); { Restore the medium sized window saved earlier }
  216. End.
  217. (**)
  218.